[XEN] Do not emulate user-mode updates to page tables.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 21 Sep 2006 18:51:10 +0000 (19:51 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 21 Sep 2006 18:51:10 +0000 (19:51 +0100)
Instead use as a hint that the page is no longer a page table.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/mm/shadow/multi.c

index 840c516fd6a14ad5665f994704b47f38f00a645c..66a3b2e2b52cfd60d406d68e1c9cb48fc5b7dd1e 100644 (file)
@@ -3037,7 +3037,14 @@ static int sh_page_fault(struct vcpu *v,
     SHADOW_PRINTK("emulate: eip=%#lx\n", emul_regs.eip);
 
     v->arch.shadow.propagate_fault = 0;
-    if ( x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) )
+
+    /*
+     * We do not emulate user writes. Instead we use them as a hint that the
+     * page is no longer a page table. This behaviour differs from native, but
+     * it seems very unlikely that any OS grants user access to page tables.
+     */
+    if ( (regs->error_code & PFEC_user_mode) ||
+         x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) )
     {
         SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
                        mfn_x(gmfn));
@@ -3050,11 +3057,10 @@ static int sh_page_fault(struct vcpu *v,
          * guest to loop on the same page fault. */
         goto done;
     }
+
+    /* Emulation triggered another page fault? */
     if ( v->arch.shadow.propagate_fault )
-    {
-        /* Emulation triggered another page fault */
         goto not_a_shadow_fault;
-    }
 
     /* Emulator has changed the user registers: write back */
     if ( hvm_guest(v) )